// ignore_for_file: constant_identifier_names, non_constant_identifier_names, unnecessary_null_comparison
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:bruno/bruno.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart' hide FormData, MultipartFile;
import '../index.dart';
import 'http_base.dart';

///
///Author: YYF
///Date: 2022-04-01 10:20:09
///Description:
///

class HttpRequestUtil {
  // static final HttpRequestUtil _instance = HttpRequestUtil._internal();
  // factory HttpRequestUtil() => _instance;
  // late Dio dio;
  // CancelToken cancelToken = CancelToken();
  // bool isTimeOut = false;
  // HttpRequestUtil._internal() {
  //   /// BaseOptions、Options、RequestOptions 都可以配置参数，优先级别依次递增，且可以根据优先级别覆盖参数
  //   dio = Dio(HttpBaseUtil().initBaseOptions(AppApi.SERVER_API_URL));

  //   ///配置 https 证书
  //   (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
  //       HttpBaseUtil().onHttpClientCreate;
  //   // 添加拦截器
  //   dio.interceptors.add(HttpBaseUtil().httpInterceptorsWrapper());
  // }

  /// restful get 操作
  /// refresh 是否下拉刷新 默认 false
  /// noCache 是否不缓存 默认 true
  /// list 是否列表 默认 false
  /// cacheKey 缓存key
  /// cacheDisk 是否磁盘缓存
  Future get(String path,
      {required Dio dio,
      Map<String, dynamic>? params,
      Options? options,
      bool refresh = false,
      bool noCache = false,
      bool list = false,
      String cacheKey = '',
      bool cacheDisk = false,
      bool showLoading = true,
      CancelToken? cancelToken,
      bool addAuthorization = true}) async {
    await HttpBaseUtil().showLoadingWidget(showLoading);

    Options requestOptions = options ?? Options();
    // requestOptions.extra ??= {};
    // requestOptions.extra!.addAll({
    //   "refresh": refresh,
    //   "noCache": noCache,
    //   "list": list,
    //   "cacheKey": cacheKey,
    //   "cacheDisk": cacheDisk,
    // });

    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization =
        HttpBaseUtil().getAuthorizationHeader();
    if (addAuthorization && authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }

    var response = await dio.get(
      path,
      queryParameters: params,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    //关闭
    // EasyLoading.dismiss();
    if (showLoading) {
      // EasyLoading.dismiss();
      BrnLoadingDialog.dismiss(Get.context!);
    }

    return response.data;
  }

  /// restful post 操作
  Future post(String path,
      {required Dio dio,
      dynamic data,
      Map<String, dynamic>? queryParameters,
      Options? options,
      bool showLoading = true,
      CancelToken? cancelToken,
      bool addAuthorization = true}) async {
    HttpBaseUtil().showLoadingWidget(showLoading);
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization =
        HttpBaseUtil().getAuthorizationHeader();
    if (addAuthorization && authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.post(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );

    //关闭
    // EasyLoading.dismiss();
    if (showLoading) {
      // EasyLoading.dismiss();
      BrnLoadingDialog.dismiss(Get.context!);
    }
    return response.data;
  }

  /// restful put 操作
  Future put(
    String path, {
    required Dio dio,
    dynamic data,
    Map<String, dynamic>? queryParameters,
    CancelToken? cancelToken,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization =
        HttpBaseUtil().getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.put(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }

  /// restful patch 操作
  Future patch(
    String path, {
    required Dio dio,
    dynamic data,
    Map<String, dynamic>? queryParameters,
    CancelToken? cancelToken,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization =
        HttpBaseUtil().getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.patch(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }

  /// restful delete 操作
  Future delete(
    String path, {
    required Dio dio,
    dynamic data,
    Map<String, dynamic>? queryParameters,
    CancelToken? cancelToken,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization =
        HttpBaseUtil().getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.delete(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }

  /// restful post form 表单提交操作
  Future postForm(
    String path, {
    required Dio dio,
    dynamic data,
    Map<String, dynamic>? queryParameters,
    CancelToken? cancelToken,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization =
        HttpBaseUtil().getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.post(
      path,
      data: FormData.fromMap(data),
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );

    return response.data;
  }

  /// restful post Stream 流数据
  Future postStream(
    String path, {
    required Dio dio,
    dynamic data,
    int dataLength = 0,
    Map<String, dynamic>? queryParameters,
    CancelToken? cancelToken,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization =
        HttpBaseUtil().getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    requestOptions.headers!.addAll({
      Headers.contentLengthHeader: dataLength.toString(),
    });
    var response = await dio.post(
      path,
      data: Stream.fromIterable(data.map((e) => [e])),
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }

  /// 上传文件，返回参数为 T
  /// [path]:请求地址
  /// [filePath]: 文件路径
  /// [params]：请求参数
  /// [success]：请求成功回调
  /// [error]：请求失败回调
  Future uploadFile<T>(String path, String filePath,
      {required Dio dio,
      Map<String, dynamic> params = const {},
      bool addAuthorization = true,
      Options? options,
      bool showSuccess = true,
      bool showLoading = true,
      bool isFromBytes = false,
      CancelToken? cancelToken,
      Uint8List? pngBytes}) async {
    try {
      late MultipartFile multipartFile;
      if (isFromBytes && pngBytes != null && pngBytes.isNotEmpty) {
        multipartFile = MultipartFile.fromBytes(pngBytes,
            filename: "${DateTime.now().millisecondsSinceEpoch}.png");
        // FormData formData = FormData.fromMap({'file': multipartFile});
      } else {
        ///压缩图片
        File file = await FlutterNativeImage.compressImage(filePath);
        //通过FormData
        // Map map = params;
        String fileName = filePath.split('.').last;
        multipartFile = await MultipartFile.fromFile(file.path,
            filename: "${DateTime.now().millisecondsSinceEpoch}.$fileName");
        // map["file"] = multipartFile;
      }
      FormData formData = FormData.fromMap({'file': multipartFile});
      if (showLoading) {
        // EasyLoading.showProgress(0, status: '上传中...');
        BrnLoadingDialog.show(Get.context!, content: '上传中...');
      }

      var response = await dio.request(
        path,
        data: formData,
        cancelToken: cancelToken,
        options: Options(
          method: 'post'.toUpperCase(),
          headers: HttpBaseUtil().getAuthorizationHeader(),
          contentType: "multipart/form-data",
        ),
        onSendProgress: (int progress, int total) {
          debugPrint("当前进度是 $progress 总进度是 $total");
          if (showLoading) {
            // EasyLoading.showProgress(progress / total, status: '上传中...');
            BrnLoadingDialog.show(Get.context!,
                content: '上传 ${progress / total} ');
          }
        },
      );
      if (response.data['code'] != null) {
        if (response.data['code'] == "200") {
          if (showLoading && showSuccess) {
            // EasyLoading.showSuccess('上传成功');
            BrnLoadingDialog.show(Get.context!, content: '上传成功');
          }
        } else {
          if (response.data['code'].toString() == "401") {
            UserStore.to.onLogout();
          }
          BrnLoadingDialog.show(Get.context!,
              content: '${response.data['message']}');
          // EasyLoading.showError(response.data['message']);
        }
      } else {
        // EasyLoading.showError('未知错误');
        toastErrorInfo('未知错误');
      }
      if (showLoading) {
        // EasyLoading.dismiss();
        BrnLoadingDialog.dismiss(Get.context!);
      }
      return response.data;
    } on DioError catch (e) {
      if (showLoading) {
        // EasyLoading.dismiss();
        BrnLoadingDialog.dismiss(Get.context!);
      }
      // EasyLoading.showError(e.toString());
      toastErrorInfo(e.toString());
    }
    return null;
  }

  ///下载文件，返回参数为 T
  /// path:请求地址
  /// savePath: 保存文件路径
  /// params：请求参数
  /// success：请求成功回调
  /// error：请求失败回调
  Future downloadFile<T>(String path, String savePath,
      {required Dio dio,
      Map<String, dynamic>? params,
      Function(double per)? progress,
      required Function() success,
      required Function() error}) async {
    try {
      var response = await dio.download(
        path,
        savePath,
        queryParameters: params,
        onReceiveProgress: (int progress, int total) {
          debugPrint("当前进度是 $progress 总进度是 $total");
          BrnLoadingDialog.show(Get.context!,
              content: '下载 ${progress / total} ');
        },
      );
      if (response != null) {
        success();
      } else {
        error();
      }
      BrnLoadingDialog.dismiss(Get.context!);
    } on DioError catch (e) {
      BrnLoadingDialog.dismiss(Get.context!);
      toastErrorInfo(e.toString());
      // EasyLoading.dismiss();
      // EasyLoading.showError(e.toString());
    }
  }
}
